using System;
using System.Data.Objects.DataClasses;
using System.Collections.Generic;

namespace Acme.Sales.EFDAL
{
	/// <summary>
	/// The event argument type of all property setters after the property is changed
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public partial class ChangedEventArgs<T> : System.ComponentModel.PropertyChangingEventArgs
	{
		/// <summary>
		/// Initializes a new instance of the ChangingEventArgs class
		/// </summary>
		/// <param name="newValue">The new value of the property being set</param>
		/// <param name="propertyName">The name of the property being set</param>
		public ChangedEventArgs(T newValue, string propertyName)
			: base(propertyName)
		{
			this.Value = newValue;
		}
		/// <summary>
		/// The new value of the property
		/// </summary>
		public T Value { get; set; }
	}

	/// <summary>
	/// The event argument type of all property setters before the property is changed
	/// </summary>
	public partial class ChangingEventArgs<T> : ChangedEventArgs<T>
	{
		/// <summary>
		/// Initializes a new instance of the ChangingEventArgs class
		/// </summary>
		/// <param name="newValue">The new value of the property being set</param>
		/// <param name="propertyName">The name of the property being set</param>
		public ChangingEventArgs(T newValue, string propertyName)
			: base(newValue, propertyName)
		{
		}
		/// <summary>
		/// Determines if this operation is cancelled.
		/// </summary>
		public bool Cancel { get; set; }
	}

	/// <summary>
	/// The interface for entities that have a created audit
	/// </summary>
	public interface ICreatedAudit
	{
		/// <summary>
		/// The created by modifier
		/// </summary>
		string CreatedBy { get; }
		/// <summary>
		/// The date this record was created
		/// </summary>
		DateTime? CreatedDate { get; }
	}

	/// <summary>
	/// The interface for entities that have a modified audit
	/// </summary>
	public interface IModifiedAudit
	{
		/// <summary>
		/// The modified by modifier
		/// </summary>
		string ModifiedBy { get; }
		/// <summary>
		/// The date this record was last updated
		/// </summary>
		DateTime? ModifiedDate { get; }
	}

	/// <summary>
	/// The interface for entities that have a concurreny audit
	/// </summary>
	public interface IConcurrencyAudit
	{
		/// <summary>
		/// A timestamp field used for concurrency operations
		/// </summary>
		byte[] TimeStamp { get; }
	}

	/// <summary>
	/// The interface for entities that implement the receiving end of the Visitor pattern
	/// </summary>
	public interface IVisitee
	{
		void ProcessVisitor(IVisitor visitor);
	}

	/// <summary>
	/// The interface for entities that implement the Visitor pattern
	/// </summary>
	public interface IVisitor
	{
		void Visit(NHEntityObject element);
	}

	/// <summary>
	/// The object type that represents the primary key object of an entity
	/// </summary>
	[Serializable]
	public partial class PrimaryKey
	{
		private Dictionary<string, object> _values = new Dictionary<string, object>();
		public Dictionary<string, object> PrimaryKeyValues { get { return _values; } }
	}

	/// <summary>
	/// The interface for entities that implement the Validation pattern
	/// </summary>
	public interface IValidation
	{
		IEnumerable<IRuleViolation> GetRuleViolations();
		bool IsValid();
	}

	/// <summary>
	/// The interface for all validation rules
	/// </summary>
	public interface IRuleViolation
	{
		string Message { get; }
	}

	/// <summary>
	/// The interface for all entities
	/// </summary>
	public interface IBusinessObject
	{
		int GetMaxLength(Enum field);
		//IPrimaryKey PrimaryKey { get; }
		bool IsEquivalent(NHEntityObject item);
	}

	internal static class GlobalValues
	{
		public const string ERROR_PROPERTY_NULL = "The value is null and in an invalid state.";
		public const string ERROR_PROPERTY_SETNULL = "Cannot set value to null.";
		public const string ERROR_CONCURRENCY_FAILURE = "Concurrency failure";
		public const string ERROR_CONSTRAINT_FAILURE = "Constraint failure";
		public const string ERROR_DATA_TOO_BIG = "The data '{0}' is too large for the {1} field which has a length of {2}.";
		public static readonly DateTime MIN_DATETIME = new DateTime(1753, 1, 1);
		public static readonly DateTime MAX_DATETIME = new DateTime(9999, 12, 31, 23, 59, 59);
	}

}
